#ifndef __PLAYER_HH__
#define __PLAYER_HH__

#include <opengl/camera.h>
#include <mc/types.h>
#include <mc/blocks.h>
#include <mc/chunkid.h>
#include <mc/handblock.h>
#include <util/tools.h>

namespace mc
{

class Player : public opengl::Camera
{
public:
    //! @brief 构造函数
    //! @param position 表示玩家脚所在的方块
    Player(const glm::vec3& position);
    ~Player() noexcept;

    //! @brief 碰撞检测
    bool collide();

    //! @brief 绘制
    void draw();

    //! @brief 玩家移动
    void move(opengl::CameraMovement direction, float deltatime);

    //! @brief 玩家下落
    void fall(float deltatime);

    //! @brief 玩家跳跃
    void jump(float deltatime);

    //! @brief 玩家潜行走
    void sneak(float deltaTime);

    //! @brief 更新玩家状态与位置
    void update(float deltatime);

    //! @brief 更改手中的物品
    void changeHodingBlock(char direction);

    //! @brief 放置方块
    void placeBlock();

    //! @brief 移除方块
    void removeBlock();

    //! @brief 切换运动方式
    void switchMovingWay();

    //! @brief 设置是否潜行
    void setSneaking(bool enable);

    //! @brief 玩家脚坐标（标准化）
    glm::vec3 footPosition() const;

    //! @brief 玩家头坐标（标准化）
    glm::vec3 headPosition() const;
    
    //! @brief 跳跃的 y 目标值
    float jumpTargetPosY() const
    { return this->_position.y + 1.3f; }

private:
    //! @brief 获得玩家指向空方块的坐标
    //! @param pos 传出参数，表示指向空气方块坐标（标准化）
    //! @return 是否存在指向的方块
    bool pointingEmptyBlock(glm::vec3& pos) const;

    //! @brief 获得玩家指向实体块的坐标
    //! @param pos 传出参数，表示指向实体方块坐标（标准化）
    //! @return 是否存在指向的方块
    bool pointingBlock(glm::vec3& pos) const;

private:
    //! @brief 摄像机
    // opengl::Camera _camera;
    ChunkID _chunkID;

    //! @brief 是否跳跃
    bool _jumping;
    //! @brief 跳跃距离
    float _jumpTargetPosY;

    //! @brief 是否飞行
    bool _flying;
    //! @brief 是否潜行
    bool _sneaking;

    //! @brief 是否下落
    bool _falling;
    //! @brief 速度
    float _fallingSpeed;

    //! @brief 手持方块
    BlockType _holdingBlock;
    HandBlock _handBlock;
};
}

#endif